﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Security.Cryptography;
using System.Xml.Linq;
using System.IO;
using System.Xml.Serialization;
namespace myFirtz.Interface
{
    public class Session
    {
        #region Properties

        private string _user;
        public string User
        {
            get
            {
                return (_user);
            }
            set
            {
                _user = value;
            }
        }

        private string _password;
        public string Password
        {
            get
            {
                return (_password);
            }
            set
            {
                _password = value;
            }
        }

        private string _sid;
        public string Sid
        {
            get
            {
                return (_sid);
            }
            set
            {
                _sid = value;
            }
        }

        private string _server;
        public string Server
        {
            get
            {
                return (_server);
            }
            set
            {
                _server = value;
            }
        }
        #endregion

        #region Constructors
        public Session()
        {
        }

        public Session(string user, string password, string server)
        {
            _user = user;
            _password = password;
            _server = server;
        }

        #endregion

        #region Public

        public bool Connect()
        {
            return (Connect(_user, _password, _server));
        }

        public bool Connect(string user, string password, string server)
        {
            _sid = string.Empty;

            _user = user;
            _password = password;
            _server = server;

            _sid = GetSessionId();
            return (!string.IsNullOrEmpty(_sid));
        }

        public List<Device> GetSwitchList()
        {
            List<Device> SwitchList = new List<Device>();
            string IdentifierList = Helper.SendCmd("", "getswitchlist", "", this);
            foreach (string Identifier in IdentifierList.Split(','))
            {
                SwitchList.Add(new Device { Identifier = Identifier });
            }

            return (SwitchList);
        }

        public string SetSwitchOn(Device Switch)
        {
            return (Helper.SendCmd(Switch.Identifier, "setswitchon", "", this));
        }

        public string SetSwitchOff(Device Switch)
        {
            return (Helper.SendCmd(Switch.Identifier, "setswitchoff", "", this));
        }

        public string SetSwitchToggle(Device Switch)
        {
            return (Helper.SendCmd(Switch.Identifier, "setswitchtoggle", "", this));
        }

        public string GetSwitchState(Device Switch)
        {
            return (Helper.SendCmd(Switch.Identifier, "getswitchstate", "", this));
        }

        public string GetSwitchPresent(Device Switch)
        {
            return (Helper.SendCmd(Switch.Identifier, "getswitchpresent", "", this));
        }

        public string GetSwitchPower(Device Switch)
        {
            return (Helper.SendCmd(Switch.Identifier, "getswitchpower", "", this));
        }

        public string GetSwitchEnergy(Device Switch)
        {
            return (Helper.SendCmd(Switch.Identifier, "getswitchenergy", "", this));
        }

        public string GetSwitchName(Device Switch)
        {
            return (Helper.SendCmd(Switch.Identifier, "getswitchname", "", this));
        }

        public DeviceList GetDeviceListInfos()
        {
            DeviceList deviceListe = new DeviceList();
            XmlSerializer serializer = new XmlSerializer(typeof(DeviceList));
            string xml = Helper.SendCmd("", "getdevicelistinfos", "", this);
            if (!string.IsNullOrEmpty(xml))
                using (TextReader reader = new StringReader(xml))
                    deviceListe = (DeviceList)serializer.Deserialize(reader);
            
            return (deviceListe);
        }

        public string GetTemperature(Device Switch)
        {
            return (Helper.SendCmd(Switch.Identifier, "gettemperature", "", this));
        }

        public string GetHKRtSoll(Device Switch)
        {
            return (Helper.SendCmd(Switch.Identifier, "gethkrtsoll", "", this));
        }

        public string GetHKRKomfort(Device Switch)
        {
            return (Helper.SendCmd(Switch.Identifier, "gethkrkomfort", "", this));
        }

        public string GetHKRAbsenk(Device Switch)
        {
            return (Helper.SendCmd(Switch.Identifier, "gethkrabsenk", "", this));
        }

        public string SetHKRtSoll(Device Switch, string param)
        {
            return (Helper.SendCmd(Switch.Identifier, "sethkrtsoll", param, this));
        }

        #endregion

        #region Private

        private string GetSessionId()
        {
            try
            {
                string uri = string.Format("http://{0}/login_sid.lua", _server);
                XDocument doc = XDocument.Load(uri);
                string sid = Helper.GetValue(doc, "SID");
                if (sid == "0000000000000000")
                {
                    string challenge = Helper.GetValue(doc, "Challenge");
                    uri = string.Format("http://{0}/login_sid.lua?username={1}&response={2}", _server, _user, GetResponse(challenge, _password));
                    doc = XDocument.Load(uri);
                    sid = Helper.GetValue(doc, "SID");
                }
                return sid;
            }
            catch (Exception ex)
            {
                Helper.LastException = ex;
                return (string.Empty);
            }
        }

        private string GetResponse(string challenge, string kennwort)
        {
            return (string.Format("{0}-{1}", challenge, Helper.GetMD5Hash(string.Format("{0}-{1}", challenge, kennwort))));
        }


        #endregion
    }
}